#include "animationmanager.h"
#include <QMessageBox>

AnimationManager::Pair* AnimationManager::GetDataByName(const QString& name)
{
    QList<Pair>::iterator current = _animations.begin();
    QList<Pair>::iterator end     = _animations.end();

    for (; current != end ; ++current)
    {
	if ((*current).first == name)
	{
	    sf::Texture* texture = _tm->GetByName(current->textureName);

	    if (texture)
	      current->second.SetTexture(texture);
	    return (&(*current));
	}
    }
    return (0);
}

Shiny::SpriteAnimate::Animation* AnimationManager::GetByName(const QString& name)
{
    QList<Pair>::iterator current = _animations.begin();
    QList<Pair>::iterator end     = _animations.end();

    for (; current != end ; ++current)
    {
	if ((*current).first == name)
	{
	  sf::Texture* texture = _tm->GetByName(current->textureName);

	  if (texture)
	    current->second.SetTexture(texture);
	  return (&((*current).second));
	}
    }
    return (0);
}

const Shiny::SpriteAnimate::Animation* AnimationManager::GetByName(const QString& name) const
{
    QList<Pair>::const_iterator current = _animations.begin();
    QList<Pair>::const_iterator end     = _animations.end();

    for (; current != end ; ++current)
    {
	if ((*current).first == name)
	  return (&((*current).second));
    }
    return (0);
}

void        AnimationManager::AddAnimation(QString name)
{
    Pair    newPair;

    newPair.first = name;
    _animations << newPair;
    AnimationAdded(name);
}

void        AnimationManager::DeleteAnimation(QString name)
{
    int res = QMessageBox::warning(0, "Suppression d'animation", "Etes-vous sur de vouloir supprimer " + name + " ?", QMessageBox::Yes, QMessageBox::No);

    if (res == QMessageBox::Yes)
    {
	QList<Pair>::iterator current = _animations.begin();
	QList<Pair>::iterator end     = _animations.end();

	for (; current != end ; ++current)
	{
	    if ((*current).first == name)
	    {
		_animations.erase(current);
		AnimationDeleted(name);
		break ;
	    }
	}
    }
}

void        AnimationManager::Load(const QString& filepath, TextureManager* tm)
{
    DataTree* file = DataTree::Factory::Yaml(filepath.toStdString());

    _tm = tm;
    if (file)
    {
	Data           anim = Data(file);
	Data::iterator it   = anim["Animations"].begin();
	Data::iterator end  = anim["Animations"].end();

	for (; it != end ; ++it)
	  LoadAnimation(*it, tm);
        delete file;
    }
}

void        AnimationManager::Save(const QString& file, TextureManager* tm)
{
    YamlStream str;

    str.newBlock("Animations");
    foreach (Pair pair, _animations)
	SaveAnimation(str, tm, pair);
    str.endBlock();
    str.SaveToFile(file);
}

void        AnimationManager::LoadAnimation(Data data, TextureManager* tm)
{
    try
    {
    Data         fieldRect = data["Rect"];
    Data         fieldText = data["Texture"];
    sf::Texture* texture;
    Pair         anim;

    if (fieldText.Nil())
      return ;
    if (!(texture = tm->GetByName(fieldText.Value().c_str())))
      return ;
    Shiny::SpriteAnimate::Animation spriteAnim(texture);
    anim.first       = data.Key().c_str();
    anim.second      = spriteAnim;
    anim.textureName = fieldText.Value().c_str();
    if (!fieldRect.Nil())
    {
        sf::IntRect rect;

	rect.Top    = fieldRect["OffsetY"];
	rect.Left   = fieldRect["OffsetX"];
	rect.Height = fieldRect["SizeY"];
	rect.Width  = fieldRect["SizeX"];
        anim.second.SetRect(rect);
    }
    anim.second.SetInLoop(data["Looping"] == "1");
    anim.second.SetRefreshRate(data["Refresh"]);
    anim.second.SetNFrames(data["Frames"]);
    _animations << anim;
    AnimationAdded(anim.first);
    }
    catch (...)
    {
	qDebug() << "Shit happened here";
    }
}

void        AnimationManager::SaveAnimation(YamlStream& stream, TextureManager* tm, Pair anim)
{
    QPair<QString, std::string> texture;
    QPair<QString, float>       frames, refresh, offsetX, offsetY, sizeX, sizeY;
    QPair<QString, bool>        loop;
    sf::IntRect                 rect = anim.second.Rect();

    frames.first    = "Frames";
    frames.second   = anim.second.NFrames();
    refresh.first   = "Refresh";
    refresh.second  = anim.second.RefreshRate();
    loop.first      = "Looping";
    loop.second     = anim.second.IsInLoop();
    offsetX.first   = "OffsetX";
    offsetX.second  = rect.Left;
    offsetY.first   = "OffsetY";
    offsetY.second  = rect.Top;
    sizeX.first     = "SizeX";
    sizeX.second    = rect.Width;
    sizeY.first     = "SizeY";
    sizeY.second    = rect.Height;
    texture.first   = "Texture";
    texture.second  = anim.textureName.toStdString();
    stream.newBlock(anim.first);
    stream << texture << frames << refresh << loop;
    stream.newBlock("Rect");
    stream << offsetX << offsetY << sizeX << sizeY;
    stream.endBlock();
    stream.endBlock();
}
